package com.kotlin.android.mtime.ktx.ext.progressdialog

import android.content.DialogInterface
import android.graphics.PorterDuff
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import androidx.core.widget.ContentLoadingProgressBar
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import com.kotlin.android.ktx.ext.e
import com.kotlin.android.mtime.ktx.R
import org.jetbrains.anko.find

/**
 * 创建者: zl
 * 创建时间: 2020/6/11 8:39 PM
 * 描述: loading框
 */
class ProgressDialogFragment : DialogFragment() {
    private var messageResId: Int? = null
    private var behavior: Behavior = Behavior.SINGLE
    private var counter = 0 // 计数器

    companion object {
        fun newInstance() = ProgressDialogFragment()

        const val TAG_PROGRESS_DIALOG_FRAGMENT = "tag_progress_dialog_fragment"
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.frag_progress_dialog, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        getView()?.find<ContentLoadingProgressBar>(R.id.progressBar)?.indeterminateDrawable?.setColorFilter(
            ContextCompat.getColor(
                view.context,
                R.color.color_dbb177
            ), PorterDuff.Mode.MULTIPLY
        )
        notifyUI()
    }

    /**
     * 设置/更新加载对话框文案提示语，可多次调用，动态更新加载对话框提示语，并且只有在加载对话框显示的情况下生效，可放心使用。
     */
    fun setLoadingTips(@StringRes resId: Int) {
        messageResId = resId
        notifyUI()
    }

    /**
     * 通知UI更新
     */
    private fun notifyUI() {
        view?.find<TextView>(R.id.messageTv)?.text = getString(messageResId ?: R.string.loading)
    }

    /**
     * 在 [Behavior.MULTIPART] 行为模式下，需要进行计数器累加
     */
    fun setBehavior(behavior: Behavior) {
        this.behavior = behavior
        if (Behavior.MULTIPART == behavior) {
            counter++
        }
    }

    /**
     * 需要关闭对话框？
     */
    private fun needDismiss(): Boolean {
        if (Behavior.MULTIPART == behavior) {
            counter--
            "ProgressDialogFragment needDismiss :: counter-- = $counter".e()
            if (counter >= 1) {
                return false
            }
        }
        return true
    }

    /**
     * 建议调用该方法关闭加载对话框
     */
    override fun dismiss() {
        if (!needDismiss()) {
            return
        }
        super.dismiss()
        resetCounter()
        "ProgressDialogFragment dismiss".e()
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        resetCounter()
        "ProgressDialogFragment onDismiss".e()
    }

    override fun dismissAllowingStateLoss() {
        super.dismissAllowingStateLoss()
        resetCounter()
        "ProgressDialogFragment dismissAllowingStateLoss".e()
    }

    /**
     * 监听到加载对话框消失时，重置计数器
     */
    private fun resetCounter() {
        counter = 0
    }

    /**
     * [ProgressDialogFragment] 的行为模式
     */
    enum class Behavior {

        /**
         * 独立模式：【建议单任务】当多次调用 [FragmentActivity.showProgressDialog] 显示加载对话框时，
         * 如果加载对话框已经处于显示状态，则不会创建新的加载对话框，只是更新加载提示语。
         *
         * 注意：存在被其他异步任务提前关闭加载对话框的风险（即：多个异步任务同时显示对话框时，先返回的将终止加载对话框）
         */
        SINGLE,

        /**
         * 多重模式：【建议多任务】当多次调用 [FragmentActivity.showProgressDialog] 显示加载对话框时，
         * 如果加载对话框已经处于显示状态，则不会创建新的加载对话框，内部将进行显示计数累加，并更新加载提示语。
         *
         * 注意：多个异步任务同时显示加载对话框时，加载对话框始终只显示一次，直到所有的异步任务都响应时才会关闭加载对话框。
         */
        MULTIPART,
    }
}